package co.edu.dataaccess.dao;

import co.edu.dataaccess.entityManager.EntityManagerHelper;

import co.edu.usbcali.modeloo.Costos;

import java.math.BigDecimal;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import javax.persistence.EntityManager;
import javax.persistence.Query;


/**
 * A data access object (DAO) providing persistence and search support for
 * Costos entities. Transaction control of the save(), update() and delete()
 * operations must be handled externally by senders of these methods or must be
 * manually added to each of these methods for data to be persisted to the JPA
 * datastore.
 *
 * @see lidis.Costos
 */
public class CostosDAO implements ICostosDAO {
    // property constants

    //public static final Integer  IDCOSTOS = "idcostos";
    public static final String IDCOSTOS = "idcostos";

    //public static final String  NOMBRE = "nombre";
    public static final String NOMBRE = "nombre";

    //public static final Integer  OTROS = "otros";
    public static final String OTROS = "otros";

    //public static final Integer  RENTA = "renta";
    public static final String RENTA = "renta";

    //public static final Integer  SALARIO = "salario";
    public static final String SALARIO = "salario";

    //public static final Integer  SERVICIOSPUBLICOS = "serviciospublicos";
    public static final String SERVICIOSPUBLICOS = "serviciospublicos";

    //public static final Integer  TOTALCOSTOS = "totalcostos";
    public static final String TOTALCOSTOS = "totalcostos";

    private EntityManager getEntityManager() {
        return EntityManagerHelper.getEntityManager();
    }

    /**
     * Perform an initial save of a previously unsaved Costos entity. All
     * subsequent persist actions of this entity should use the #update()
     * method. This operation must be performed within the a database
     * transaction context for the entity's data to be permanently saved to the
     * persistence store, i.e., database. This method uses the
     * {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
     * operation.
     *
     * <pre>
     * EntityManagerHelper.beginTransaction();
     * CostosDAO.save(entity);
     * EntityManagerHelper.commit();
     * </pre>
     *
     * @param entity
     *            Costos entity to persist
     * @throws RuntimeException
     *             when the operation fails
     */
    public void save(Costos entity) {
        EntityManagerHelper.log("saving Costos instance", Level.INFO, null);

        try {
            getEntityManager().persist(entity);
            EntityManagerHelper.log("save successful", Level.INFO, null);
        } catch (RuntimeException re) {
            EntityManagerHelper.log("save failed", Level.SEVERE, re);
            throw re;
        }
    }

    /**
     * Delete a persistent Costos entity. This operation must be performed
     * within the a database transaction context for the entity's data to be
     * permanently deleted from the persistence store, i.e., database. This
     * method uses the
     * {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
     * operation.
     *
     * <pre>
     * EntityManagerHelper.beginTransaction();
     * CostosDAO.delete(entity);
     * EntityManagerHelper.commit();
     * entity = null;
     * </pre>
     *
     * @param entity
     *            Costos entity to delete
     * @throws RuntimeException
     *             when the operation fails
     */
    public void delete(Costos entity) {
        EntityManagerHelper.log("deleting Costos instance", Level.INFO, null);

        try {
            entity = getEntityManager()
                         .getReference(Costos.class, entity.getIdcostos());
            getEntityManager().remove(entity);
            EntityManagerHelper.log("delete successful", Level.INFO, null);
        } catch (RuntimeException re) {
            EntityManagerHelper.log("delete failed", Level.SEVERE, re);
            throw re;
        }
    }

    /**
     * Persist a previously saved Costos entity and return it or a copy of it
     * to the sender. A copy of the Costos entity parameter is returned when
     * the JPA persistence mechanism has not previously been tracking the
     * updated entity. This operation must be performed within the a database
     * transaction context for the entity's data to be permanently saved to the
     * persistence store, i.e., database. This method uses the
     * {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
     * operation.
     *
     * <pre>
     * EntityManagerHelper.beginTransaction();
     * entity = CostosDAO.update(entity);
     * EntityManagerHelper.commit();
     * </pre>
     *
     * @param entity
     *            Costos entity to update
     * @return Costos the persisted Costos entity instance, may not be the
     *         same
     * @throws RuntimeException
     *             if the operation fails
     */
    public Costos update(Costos entity) {
        EntityManagerHelper.log("updating Costos instance", Level.INFO, null);

        try {
            Costos result = getEntityManager().merge(entity);
            EntityManagerHelper.log("update successful", Level.INFO, null);

            return result;
        } catch (RuntimeException re) {
            EntityManagerHelper.log("update failed", Level.SEVERE, re);
            throw re;
        }
    }

    public Costos findById(Integer id) {
        EntityManagerHelper.log("finding Costos instance with id: " + id,
            Level.INFO, null);

        try {
            Costos instance = getEntityManager().find(Costos.class, id);

            return instance;
        } catch (RuntimeException re) {
            EntityManagerHelper.log("find failed", Level.SEVERE, re);
            throw re;
        }
    }

    /**
     * Find all  Costos entities with a specific property value.
     *
     * @param propertyName
     *            the metaData.name of the  Costos property to query
     * @param value
     *            the property value to match
     * @return List< Costos> found by query
     */
    @SuppressWarnings("unchecked")
    public List<Costos> findByProperty(String propertyName, final Object value) {
        EntityManagerHelper.log("finding  Costos instance with property: " +
            propertyName + ", value: " + value, Level.INFO, null);

        try {
            final String queryString = "select model from  Costos model where model." +
                propertyName + "= :propertyValue";
            Query query = getEntityManager().createQuery(queryString);
            query.setParameter("propertyValue", value);

            return query.getResultList();
        } catch (RuntimeException re) {
            EntityManagerHelper.log("find by property metaData.name failed",
                Level.SEVERE, re);
            throw re;
        }
    }

    /**
     * Find all Costos entities with a specific property value.
     *
     * @param propertyName
     *            the name of the Costos property to query
     * @param value
     *            the property value to match
     * @param rowStartIdxAndCount
     *            Optional int varargs. rowStartIdxAndCount[0] specifies the the
     *            row index in the query result-set to begin collecting the
     *            results. rowStartIdxAndCount[1] specifies the the maximum
     *            number of results to return.
     * @return List<Costos> found by query
     */
    @SuppressWarnings("unchecked")
    public List<Costos> findByProperty(String propertyName, final Object value,
        final int... rowStartIdxAndCount) {
        EntityManagerHelper.log("finding Costos instance with property: " +
            propertyName + ", value: " + value, Level.INFO, null);

        try {
            final String queryString = "select model from Costos model where model." +
                propertyName + "= :propertyValue";
            Query query = getEntityManager().createQuery(queryString);
            query.setParameter("propertyValue", value);

            if ((rowStartIdxAndCount != null) &&
                    (rowStartIdxAndCount.length > 0)) {
                int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);

                if (rowStartIdx > 0) {
                    query.setFirstResult(rowStartIdx);
                }

                if (rowStartIdxAndCount.length > 1) {
                    int rowCount = Math.max(0, rowStartIdxAndCount[1]);

                    if (rowCount > 0) {
                        query.setMaxResults(rowCount);
                    }
                }
            }

            return query.getResultList();
        } catch (RuntimeException re) {
            EntityManagerHelper.log("find by property name failed",
                Level.SEVERE, re);
            throw re;
        }
    }

    public List<Costos> findByIdcostos(Object idcostos,
        int... rowStartIdxAndCount) {
        return findByProperty(IDCOSTOS, idcostos, rowStartIdxAndCount);
    }

    public List<Costos> findByIdcostos(Object idcostos) {
        return findByProperty(IDCOSTOS, idcostos);
    }

    public List<Costos> findByNombre(Object nombre, int... rowStartIdxAndCount) {
        return findByProperty(NOMBRE, nombre, rowStartIdxAndCount);
    }

    public List<Costos> findByNombre(Object nombre) {
        return findByProperty(NOMBRE, nombre);
    }

    public List<Costos> findByOtros(Object otros, int... rowStartIdxAndCount) {
        return findByProperty(OTROS, otros, rowStartIdxAndCount);
    }

    public List<Costos> findByOtros(Object otros) {
        return findByProperty(OTROS, otros);
    }

    public List<Costos> findByRenta(Object renta, int... rowStartIdxAndCount) {
        return findByProperty(RENTA, renta, rowStartIdxAndCount);
    }

    public List<Costos> findByRenta(Object renta) {
        return findByProperty(RENTA, renta);
    }

    public List<Costos> findBySalario(Object salario, int... rowStartIdxAndCount) {
        return findByProperty(SALARIO, salario, rowStartIdxAndCount);
    }

    public List<Costos> findBySalario(Object salario) {
        return findByProperty(SALARIO, salario);
    }

    public List<Costos> findByServiciospublicos(Object serviciospublicos,
        int... rowStartIdxAndCount) {
        return findByProperty(SERVICIOSPUBLICOS, serviciospublicos,
            rowStartIdxAndCount);
    }

    public List<Costos> findByServiciospublicos(Object serviciospublicos) {
        return findByProperty(SERVICIOSPUBLICOS, serviciospublicos);
    }

    public List<Costos> findByTotalcostos(Object totalcostos,
        int... rowStartIdxAndCount) {
        return findByProperty(TOTALCOSTOS, totalcostos, rowStartIdxAndCount);
    }

    public List<Costos> findByTotalcostos(Object totalcostos) {
        return findByProperty(TOTALCOSTOS, totalcostos);
    }

    /**
     * Find all Costos entities.
     *
     * @param rowStartIdxAndCount
     *            Optional int varargs. rowStartIdxAndCount[0] specifies the the
     *            row index in the query result-set to begin collecting the
     *            results. rowStartIdxAndCount[1] specifies the the maximum
     *            count of results to return.
     * @return List<Costos> all Costos entities
     */
    @SuppressWarnings("unchecked")
    public List<Costos> findAll(final int... rowStartIdxAndCount) {
        EntityManagerHelper.log("finding all Costos instances", Level.INFO, null);

        try {
            final String queryString = "select model from Costos model";
            Query query = getEntityManager().createQuery(queryString);

            if ((rowStartIdxAndCount != null) &&
                    (rowStartIdxAndCount.length > 0)) {
                int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);

                if (rowStartIdx > 0) {
                    query.setFirstResult(rowStartIdx);
                }

                if (rowStartIdxAndCount.length > 1) {
                    int rowCount = Math.max(0, rowStartIdxAndCount[1]);

                    if (rowCount > 0) {
                        query.setMaxResults(rowCount);
                    }
                }
            }

            return query.getResultList();
        } catch (RuntimeException re) {
            EntityManagerHelper.log("find all failed", Level.SEVERE, re);
            throw re;
        }
    }

    public List<Costos> findByCriteria(String whereCondition) {
        try {
            String where = ((whereCondition == null) ||
                (whereCondition.length() == 0)) ? "" : ("where " +
                whereCondition);

            final String queryString = "select model from Costos model " +
                where;

            Query query = getEntityManager().createQuery(queryString);

            List<Costos> entitiesList = query.getResultList();

            return entitiesList;
        } catch (RuntimeException re) {
            EntityManagerHelper.log("find By Criteria in Costos failed",
                Level.SEVERE, re);
            throw re;
        }
    }

    public List<Costos> findPageCostos(String sortColumnName,
        boolean sortAscending, int startRow, int maxResults) {
        if ((sortColumnName != null) && (sortColumnName.length() > 0)) {
            try {
                String queryString = "select model from Costos model order by model." +
                    sortColumnName + " " + (sortAscending ? "asc" : "desc");

                return getEntityManager().createQuery(queryString)
                           .setFirstResult(startRow).setMaxResults(maxResults)
                           .getResultList();
            } catch (RuntimeException re) {
                throw re;
            }
        } else {
            try {
                String queryString = "select model from Costos model";

                return getEntityManager().createQuery(queryString)
                           .setFirstResult(startRow).setMaxResults(maxResults)
                           .getResultList();
            } catch (RuntimeException re) {
                throw re;
            }
        }
    }

    @SuppressWarnings("unchecked")
    public Long findTotalNumberCostos() {
        try {
            String queryString = "select count(*) from Costos model";

            return (Long) getEntityManager().createQuery(queryString)
                              .getSingleResult();
        } catch (RuntimeException re) {
            throw re;
        }
    }
}
